package com.huang.wishstar.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huang.wishstar.entity.RequestData.Login;
import com.huang.wishstar.entity.RequestData.Register;
import com.huang.wishstar.entity.RequestData.UpdatePwd;
import com.huang.wishstar.entity.RequestData.UpdateUserMsg;
import com.huang.wishstar.entity.Users;
import com.huang.wishstar.entity.vo.GetHabitWishesVO;
import com.huang.wishstar.service.CheckcodeService;
import com.huang.wishstar.service.UsersService;
import com.huang.wishstar.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

import java.time.LocalDateTime;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author hmx
 * @since 2021-09-13
 */
@Api(tags = "用户管理" ,description = "UserController")
@RestController
@RequestMapping("/users")
public class UsersController {
    @Autowired
    private UsersService usersService;
    @Autowired
    private CheckcodeService checkcodeService;
    @Autowired
    MyEmail myEmail;
    @Resource
    private RedisUtil redisUtil;

    /*初始测试index.html*/
//    @GetMapping("/index")
//    public ModelAndView index(){
//        ModelAndView modelAndView = new ModelAndView();
//        modelAndView.setViewName("index");
//        modelAndView.addObject("list",usersService.list());
//        return modelAndView;
//    }
    @ApiOperation(value = "注册和忘记密码页/获取邮箱验证码", notes = "点击按钮获取邮箱验证码。此处返回验证码仅做测试时使用，实际要从邮箱获取")
    @GetMapping("/getCheckCode")
    @ResponseBody
    public ApiResponse<String> sendEmail(@ApiParam(value="用户邮箱",required = true) @RequestParam(value="userMail",required=true) String userMail,
                                         @ApiParam(value="该验证码用处(1为注册，2为修改密码)",required = true) @RequestParam(value="state",required=true) int state) {
        /*先判断邮箱是否已经注册过，即是否已经存在于users表中，使用的是count方法*/
        QueryWrapper<Users> wrapper = new QueryWrapper<>();
        wrapper.eq("user_mail",userMail);//要和数据库的一样，带下划线的不能转大写
        int registerNum = usersService.count(wrapper);
        System.out.println("registerNum="+registerNum);
        //注册时的验证码必须保证邮箱未被注册过，修改密码时的验证码必须保证该邮箱有用户使用
        if(state==1){
            if(registerNum !=0){
                return ApiResponse.<String>builder().code(400).message("该邮箱已被注册").data(null).build();
            }
        }
        if(state==2){
            if(registerNum ==0){
                return ApiResponse.<String>builder().code(400).message("该邮箱未被注册，无法修改密码").data(null).build();
            }
        }
        /*调用发送邮件工具类，向用户邮箱发送验证码；工具类会返回给控制层验证码，以便存到redis*/
        String checkCode =null;
        if(state==1){checkCode = myEmail.registerMail(userMail);}
        if(state==2){checkCode = myEmail.updatePwdMail(userMail);}
        if(checkCode == "error"){
            return ApiResponse.<String>builder().code(400).message("输入的邮箱无效，请稍后重试").data(null).build();
        }
//        /*方法一：在数据库建一张验证码的表，实现容易，但不建议这样*/
//        Checkcode checkcodeEntity = new Checkcode();
//        checkcodeEntity.setCode(checkCode);
//        checkcodeEntity.setMail(userMail);
//        checkcodeEntity.setDate(new Date());
//        checkcodeMapper.insert(checkcodeEntity);
        /*方法二：使用redis缓存验证码*/
        //调用redis工具类的set方法，第三个参数time的单位是秒
        int redisFlag = 0;
        if(state==1){ redisUtil.set("register"+userMail,checkCode,600);redisFlag=1;}
        if(state==2){ redisUtil.set("updatePwd"+userMail,checkCode,900);redisFlag=2;}
        if(redisFlag !=0){
            return ApiResponse.<String>builder().code(200).message("获取成功").data(checkCode).build();
        }else{
            return ApiResponse.<String>builder().code(400).message("服务器端验证码缓存失败").data(null).build();
        }
    }

    /**
     * 验证注册信息并且保存用户数据
     */
    @ApiOperation(value = "注册页/用户注册", notes = "先验证注册信息即验证码是否匹配，匹配则新建用户记录。注册成功后返回用户userId，类型为Integer")
    @PostMapping("/register")
    public ApiResponse<Integer> register(@ApiParam(value="用户信息",required = true) @RequestBody(required=true) Register requestData) throws JsonProcessingException {
        //步骤1：获取前端发来的验证信息
        String code = requestData.getCode();
        String userMail = requestData.getUserMail();
        QueryWrapper<Users> wrapperMail = new QueryWrapper<>();
        wrapperMail.eq("user_mail",userMail).last("limit 1");
        int isUserExist = usersService.count(wrapperMail);
        if(isUserExist != 0){
            return ApiResponse.<Integer>builder().code(400).message("该邮箱已经被注册").data(null).build();
        }

        //步骤2：取出验证码（方法一从数据表取；方法二从redis取）
            /*方法一：将验证码存入数据库的表的写法*/
//        QueryWrapper wrapper = new QueryWrapper();
//        wrapper.eq("mail",userMail);
//        wrapper.orderByDesc("id");
//        String trueCode = checkcodeMapper.selectOne(wrapper).getCode();

        /*方法二：从redis取出缓存的验证码，键为邮箱，值为验证码，设定的时间到了该缓存就会被删除，也就不能通过键找到对应的验证码*/
        String checkCode = (new ObjectMapper()).writeValueAsString(redisUtil.get("register"+userMail));//取出验证码，由于工具类取出的时object，需要类型转换
        System.out.println("redis中该邮箱对应的验证码为："+checkCode+",用户输入的验证码为"+code+",checkcode长度为："+checkCode.length()+"去双引号后的长度"+checkCode.replace("\"", "")+"" );

        //失败之后重新注册
        if (userMail == null || userMail.isEmpty()) {
            return ApiResponse.<Integer>builder().code(400).message("用户邮箱有误").data(null).build();
        } else if (!code.equals(checkCode.replace("\"", ""))) {
            return ApiResponse.<Integer>builder().code(400).message("验证码错误").data(null).build();
        }

//       验证成功则新建一条用户记录
        Users userEntity =new Users();
        userEntity.setUserMail(userMail);
        userEntity.setPassword(requestData.getPassword());
        userEntity.setNickname(requestData.getNickname());
        userEntity.setMotto("我是一个小萌新~");
        userEntity.setDeleted(0);
        userEntity.setGmtCreate(LocalDateTime.now());
        //System.out.println("插入前userid："+userEntity.getUserId());//null
        usersService.save(userEntity);
        System.out.println("插入后的userid："+userEntity.getUserId());//插入后会得到自增id

//		下边返回的就是注册成功之后的跳转了
        return ApiResponse.<Integer>builder().code(200).message("注册成功").data(userEntity.getUserId()).build();
    }

    /**
     * 用户登录
     */
    @ApiOperation(value = "登录页/用户登录", notes = "")
    @PostMapping("/login")
    public ApiResponse<Integer> login(@ApiParam(value="用户邮箱和密码",required = true) @RequestBody(required=true) Login requestData) throws JsonProcessingException {
        //步骤1：获取前端发来的数据
        String userMail = requestData.getUserMail();
        String password = requestData.getPassword();
        //步骤2：从数据库用户表取出该用户
        QueryWrapper<Users> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("user_mail",userMail).last("limit 1");
        QueryWrapper<Users> wrapper2 = new QueryWrapper<>();
        wrapper2.eq("user_mail",userMail).eq("password",password).last("limit 1");
        int isUserExist = usersService.count(wrapper1);
        int isPwdRight = usersService.count(wrapper2);
        Users userEntity = usersService.getOne(wrapper2);
        System.out.println("该邮箱密码对应的用户信息为："+userEntity);
        if(isUserExist==0){
            return ApiResponse.<Integer>builder().code(400).message("该邮箱未注册").data(null).build();
        }
        if(isPwdRight==0){
            return ApiResponse.<Integer>builder().code(400).message("邮箱或密码错误").data(null).build();
        }
        return ApiResponse.<Integer>builder().code(200).message("登录成功,返回用户id").data(userEntity.getUserId()).build();
    }


    /**
     * 验证邮箱信息并修改密码
     */
    @ApiOperation(value = "忘记密码页/用户修改密码", notes = "先判断验证码是否匹配，然后再修改用户密码")
    @PutMapping("/updatePwd")
    public ApiResponse<String> updatePwd(@ApiParam(value="用户新密码",required = true) @RequestBody(required=true) UpdatePwd requestData) throws JsonProcessingException {
        //步骤1：获取前端发来的验证信息
        String code = requestData.getCode();
        String userMail = requestData.getUserMail();
        /*从redis取出缓存的验证码，键为邮箱，值为验证码，设定的时间到了该缓存就会被删除，也就不能通过键找到对应的验证码*/
        String checkCode = (new ObjectMapper()).writeValueAsString(redisUtil.get("updatePwd"+userMail));//取出验证码，由于工具类取出的时object，需要类型转换
//        System.out.println("redis中该邮箱对应的验证码为："+checkCode+",用户输入的验证码为"+code+",checkcode长度为："+checkCode.length()+"去双引号后的长度"+checkCode.replace("\"", "")+"" );

        //失败提示
        if (userMail == null || userMail.isEmpty()) {
            return ApiResponse.<String>builder().code(400).message("用户邮箱有误").data(null).build();
        } else if (!code.equals(checkCode.replace("\"", ""))) {
            return ApiResponse.<String>builder().code(400).message("验证码错误").data(null).build();
        }

        // 验证成功则修改用户密码
        Users userEntity = new Users();
        userEntity.setPassword(requestData.getPassword());
        LocalDateTime  localDateTime= LocalDateTime.now();
        userEntity.setGmtModified(localDateTime);
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("user_mail",userMail);
        usersService.update(userEntity,wrapper);
//		下边返回的就是注册成功之后的跳转了
        return ApiResponse.<String>builder().code(200).message("修改密码成功").data(null).build();
    }


    @ApiOperation(value = "我的页/修改用户信息", notes = "只传需要修改的参数.")
    @PutMapping("/updateUserMsg")
    public ApiResponse<String> updateUserById(@ApiParam(value="修改用户信息：userId必传，其他字段不修改的就删掉，只传要修改的字段",required = true) @RequestBody(required=true) UpdateUserMsg requestData){
        //先以userId往用户表查找，如果不存在，则无法修改；如果存在，在原来的记录上更新需要修改的字段即可。
        Users userEntity = usersService.getById(requestData.getUserId());
        if (userEntity ==null){
            return ApiResponse.<String>builder().code(400).message("修改失败,输入的id有误，该用户不存在").data("fail").build();
        }
        if((requestData.getNickname())!=null ){
            userEntity.setPhone(requestData.getPhone());
        }
        if(requestData.getMotto() != null){
            userEntity.setMotto(requestData.getMotto());
        }
        if(requestData.getPhone() != null){
            userEntity.setPassword(requestData.getPhone());
        }
        if(requestData.getHeadImage() != null){
            userEntity.setHeadImage(requestData.getHeadImage());
        }

        userEntity.setGmtModified(LocalDateTime.now());
        Boolean updateFlag = usersService.updateById(userEntity);
        if (updateFlag == true){
            return ApiResponse.<String>builder().code(200).message("修改成功").data(updateFlag.toString()).build();
        }
        else {
            return ApiResponse.<String>builder().code(400).message("修改失败").data(updateFlag.toString()).build();
        }
    }

    @ApiOperation(value = "我的页/查找某用户信息", notes = "")
    @GetMapping("/getUserInfo/{userId}")
    @ResponseBody
    public ApiResponse<Users> getUserInfo(@ApiParam(value="用户id",required = true) @PathVariable(value="userId",required=true) Integer userId) {
        //先判断用户是否存在
        QueryWrapper<Users> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("user_id",userId).last("limit 1");
        int isUserExist = usersService.count(wrapper1);
        if(isUserExist == 0){
            return ApiResponse.<Users>builder().code(400).message("用户id有误").data(null).build();
        }
        Users userEntity = usersService.getById(userId);
        if(userEntity !=null){
            return ApiResponse.<Users>builder().code(200).message("获取成功").data(userEntity).build();
        }else{
            return ApiResponse.<Users>builder().code(400).message("获取失败").data(null).build();
        }

    }



}

